系列說明 >> 本系列大部分 PR 來自私人或公司專案,部分程式碼、環境設定與實作細節不便公開。
我只能保證文中提到的 PR 與問題皆為真實案例,但會經過必要的匿名化與內容調整。
本系列主要分享問題如何被發現、背後的思考方式,以及解法如何形成,不會深入討論完整實作與部署細節,敬請見諒。
Base Repo: paulshaclaw
Issue: Job Registry 與 Exit Sentinel 已能指出 Agent Process 是否結束,但 Builder 完成、Reviewer 通過、Handoff 產生與下游工作放行仍是四件分開的事。沒有人持續推進時,Workflow 會停在一堆各自「完成」的 Job 中間。
Root Cause: 系統只有 durable job state,沒有 durable completion lifecycle;done 被當成單一布林值,卻沒有明確表示誰 Poll、誰 Gate、交接 Artifact 在哪,以及下游何時可以開始。
Solution: 建立 poll → gate → handoff manifest → release downstream 的完成鏈;再由 systemd manager 週期性執行,讓派工不再是一次性 Command,而是一條能跨 Process 持續推進的 Lifecycle。
Evidence: PR #133/#134 的實作與 regression coverage 支持 Poll、Gate、Handoff 與 Downstream Release 已被接成同一條控制路徑,並由 systemd manager 週期化。這些證據能證明 Lifecycle Mechanism 與邊界已落地;本文不把它升級成長時間無人值守的 Production Soak 已完成。
DONE,我差點就收工了群裡第一個回來的是小bu。
「Done。」
後面跟著一串 Commit、Test Result,還有它一貫的積極。
小re也看完了。
「目前沒有 Blocking Finding。」
我看了一眼時間。
很好。
今天居然有機會準時吃飯。
正準備把這件事從腦袋裡劃掉,小ma丟出兩個字:
「還沒。」
這種人真的很不適合負責團隊士氣。
小bu已經做完。
小re也沒有擋。
Agent Process 正常退出,Exit Sentinel 有結果,Job Registry 也不是失蹤人口。
到底還沒什麼?
小ma把後面的工作列出來:
Builder Done
→ Review Gate
→ 產生交接資料
→ 放行下一個 Job
前兩格有了。
後兩格還在等人。
那個人目前就是我。
done 這個字,至少藏了四種不同意思以前只有一隻 Agent 時,done 很單純。
它回來,我看一下。
沒問題,就接著做下一件事。
多 Agent 之後,同一個字開始各懷鬼胎:
Process Done
= Agent CLI 已經退出
Build Done
= Builder 認為工作做完
Review Done
= Reviewer 已經給出 Verdict
Workflow Done
= 所有必要 Transition 已完成
這四件事可能同時發生。
也可能完全不同步。
例如小bu的 Process 已退出,但 Test 沒跑完。
也可能 Test 全綠,小re仍然提出 Blocking Finding。
甚至小re已經放行,但下游根本不知道該讀哪一份 Artifact。
所以 Exit Code 只能證明:
這個 Process 結束了。
它不能自動推導:
這份工作可以往下一關走。
更不能推導:
下一關已經開始。
這個差異看起來很基本。
現場卻很容易被一個綠色 0 麻醉。
工程師看到 Exit Code 0,腦內多巴胺先行上線;至於下一個 Transition 有沒有真的發生,通常等明天早上才知道。
既然缺的是「下一步」,最便宜的做法當然是:
Agent 做完後,傳一則通知。
例如:
Job A completed
我看到後,再手動:
找 Review Result。
判斷 Gate。
整理下游需要的資訊。
啟動下一個 Job。
這確實比我一直切 Pane 好。
只是工作仍然長這樣:
Job A completed
↓
通知我
↓
我去找 Verdict
↓
我整理 Context
↓
我叫 Job B 開始
我們只是把「主動巡邏」改成「收到通知後值班」。
人肉 Scheduler 沒有下班。
它只是開了 Push Notification。
老Go看了一眼。
「所以系統現在會主動提醒你來做系統該做的事?」
「……對。」
「很智慧。」
謝謝。
真正要補的不是通知。
是 Transition。
一份上游工作結束後,至少要依序回答:
結果回來了嗎?
→ Poll
證據足夠放行嗎?
→ Gate
下游要接什麼?
→ Handoff Manifest
條件成立後,誰可以開始?
→ Release Downstream
這就是 PR #133 補上的 Completion Lifecycle。
先不要被名字嚇到。
它沒有在做什麼神祕大法。
只是把我原本手動做的四個動作,變成一條看得見、可以重跑、也可以停住的流程。
重點是「可以停住」。
如果 Gate 不通過,流程就停在 Gate。
不能因為 Builder 很努力、Process 也正常退出,就順手把下游一起放出去。
小bu的偏見是:
看到問題就想解。
小re的偏見是:
看到主張就想找洞。
小ma的偏見開始變得非常穩定:
只要 Lifecycle 還有一格沒完成,就不承認這件事已經完成。
所以它不是看不懂大家的努力。
它只是對「差不多可以了」這種狀態有生理性排斥。
上游通過 Gate 後,下游還需要知道自己要接什麼。
以前這些資訊常常藏在對話裡:
剛才那隻改了哪些檔案
測了什麼
哪個 Finding 已解
哪個限制仍保留
下一隻從哪裡開始
如果我還記得,就直接貼給下一隻。
如果我忘了,就重新讀一次。
如果 Context 剛好斷掉,就大家一起考古。
這種 Workflow 也不是不能運作。
只是每次 Handoff 都像換班時口頭交接:
「大概好了,你接著看一下。」
然後下一班從頭 Survey。
Handoff Manifest 的作用,就是把交接需要的資訊變成 Artifact。
它不等於完整 Transcript,也不需要把上一隻 Agent 的一生全塞進去。
它只需要讓下游回答:
我接到的是哪份 Work?
上游交付了什麼?
Gate 根據什麼放行?
還有哪些限制?
下一步被允許做什麼?
所以 Gate PASS 後,不是群裡放一張煙火貼圖。
是產生一張交接單。
煙火很療癒。
交接單比較能避免重工。
PR #133 把 Completion Lifecycle 接起來後,還有一個很現實的問題。
誰來定期跑它?
若每次仍然要我手動下:
manager poll
那它只是把四個人工步驟包成一個比較長的 Command。
我依然要記得執行。
小ma也就像一位只有被點名才上班的值班員。
PR #134 接著把這條路徑放進 systemd manager,週期性檢查待處理工作。
概念上是:
定期醒來
→ 找出需要 Poll 的 Job
→ 檢查 Gate
→ 產生 Handoff
→ 符合條件才 Release
→ 回去睡
它不是讓一個 LLM 永遠掛在背景深思熟慮。
也不是每隔幾秒重讀整個世界。
只是把規則已經明確的 Lifecycle 推進,交給一個會固定醒來的 Manager Process。
這個差異很重要。
因為「自主」最容易被寫成:
放一隻很貴的 Agent 在背景一直看。
看久了它不一定更懂。
帳單倒是很懂。
能用 state 與 transition 解決的事情,先不要叫模型來冥想。
PR #133/#134 能支持的主張是:
Job 結束後,Manager 有路徑可以 Poll。
Gate 會決定能不能繼續。
Handoff Artifact 可以交給下游。
Downstream Release 不再只靠我記得。
這條 Lifecycle 可以由 systemd manager 週期推進。
它不能直接證明:
所有 Workflow 都已經長時間無人值守穩定運轉。
也不能證明:
Manager 之後不再需要 Human Judgment。
Gate 需要人時,還是得停。
Evidence 不夠時,還是不能放。
真正的改變不是「人消失了」。
而是人不再負責每一次正常 Transition。
小ma開始替我做那些規則已經明確、卻很容易忘記的接棒工作。
這就夠有用了。
至少我不用在吃飯時突然想起:
等等,剛才那隻小bu通過 Review 之後,我是不是忘了叫下一隻?
不過,Workflow 開始會自己接棒後,我很快就想把它用在更大的工作上。
一份 Plan 放在管理 Repo,實作卻分散到另一個 Repo,還想一次派出十個小工。
小ma先檢查:
「Ready。」
然後第一隻 Canary 連門都走不出去。
下一篇,小re會問小ma一個讓整個群突然安靜的問題:
「你剛才說 Ready,是拿哪一份 Plan 判的?」
Have a nice day.